package com.xiaoyu.net;

import com.xiaoyu.net.config.Constant;
import com.xiaoyu.net.dns.DnsProxy;
import com.xiaoyu.net.intercept.RefreshTokenInterceptorProxy;

import java.security.cert.X509Certificate;

import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;

public class OkHttpClientSupplier {

    public static final DnsProxy DNS_PROXY = new DnsProxy();
    public static final RefreshTokenInterceptorProxy REFRESH_TOKEN_INTERCEPTOR_PROXY = new RefreshTokenInterceptorProxy();
    private static final OkHttpClient CLIENT = createHttpClient();
    private static final OkHttpClient RES_CLIENT = createHttpResClient();

    public static OkHttpClient get() {
        return CLIENT;
    }

    public static OkHttpClient getResClient() {
        return RES_CLIENT;
    }

    private static OkHttpClient createHttpClient() {
        return new OkHttpClient.Builder()
                .connectTimeout(Constant.TIMEOUT, TimeUnit.MILLISECONDS)
                .readTimeout(Constant.TIMEOUT, TimeUnit.MILLISECONDS)
                .writeTimeout(Constant.TIMEOUT, TimeUnit.MILLISECONDS)
                .addInterceptor(REFRESH_TOKEN_INTERCEPTOR_PROXY)
                .retryOnConnectionFailure(true)
                .dns(DNS_PROXY)
                .build();
    }

    private static OkHttpClient createHttpResClient() {
        try {
            final TrustManager[] trustManagers = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[]{};
                        }
                    }
            };

            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustManagers, new java.security.SecureRandom());
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            return new OkHttpClient.Builder()
                    .connectTimeout(Constant.TIMEOUT, TimeUnit.MILLISECONDS)
                    .readTimeout(Constant.TIMEOUT, TimeUnit.MILLISECONDS)
                    .writeTimeout(Constant.TIMEOUT, TimeUnit.MILLISECONDS)
                    .retryOnConnectionFailure(true)
                    .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManagers[0])
                    .hostnameVerifier((hostname, session) -> true)
                    .dns(DNS_PROXY)
                    .build();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return new OkHttpClient.Builder().build();
        }
    }
}